<?php
Yii::import( "xupload.models.XUploadForm" );

/**
 * XUploadAction
 * =============
 * Basic upload functionality for an action used by the xupload extension.
 *
 * XUploadAction is used together with XUpload and XUploadForm to provide file upload funcionality to any application
 *
 * You must configure properties of XUploadAction to customize the folders of the uploaded files.
 *
 * Using XUploadAction involves the following steps:
 *
 * 1. Override CController::actions() and register an action of class XUploadAction with ID 'upload', and configure its
 * properties:
 * ~~~
 * [php]
 * class MyController extends CController
 * {
 *     public function actions()
 *     {
 *         return array(
 *             'upload'=>array(
 *                 'class'=>'xupload.actions.XUploadAction',
 *                 'path' =>Yii::app() -> getBasePath() . "/../uploads",
 *                 'publicPath' => Yii::app() -> getBaseUrl() . "/uploads",
 *                 'subfolderVar' => "parent_id",
 *             ),
 *         );
 *     }
 * }
 *
 * 2. In the form model, declare an attribute to store the uploaded file data, and declare the attribute to be validated
 * by the 'file' validator.
 * 3. In the controller view, insert a XUpload widget.
 *
 * ###Resources
 * - [xupload](http://www.yiiframework.com/extension/xupload)
 *
 * @version 0.3
 * @author Asgaroth (http://www.yiiframework.com/user/1883/)
 */
class XUploadAction extends CAction {
	/**
	 * 
	 * Allowed Myme Types for image uploading
	 */
	private $allowedTypes = array('image/gif', 'image/png', 'image/jpeg', 'image/pjpeg');
    private $uploadedImagePath;
    private $imageName;
    private $imagenId;
    private $mimeType;
    private $size;
    private $resize = false;
    /**
     * The query string variable name where the subfolder name will be taken from.
     * If false, no subfolder will be used.
     * Defaults to null meaning the subfolder to be used will be the result of date("mdY").
     *
     * @see XUploadAction::init().
     * @var string
     * @since 0.2
     */
    public $subfolderVar = false;

    /**
     * Path of the main uploading folder.
     * @see XUploadAction::init()
     * @var string
     * @since 0.1
     */
    public $path;

    /**
     * Public path of the main uploading folder.
     * @see XUploadAction::init()
     * @var string
     * @since 0.1
     */
    public $publicPath;

    /**
     * The resolved subfolder to upload the file to
     * @var string
     * @since 0.2
     */
    private $_subfolder = "";

    /**
     * Initialize the propeties of pthis action, if they are not set.
     *
     * @since 0.1
     */
    public function init( ) {
        if( !isset( $this->path ) ) {
            $this->path = realpath( Yii::app( )->getBasePath( )."/../uploads" );
        }

        if( !is_dir( $this->path ) ) {
            mkdir( $this->path, 0777, true );
            chmod ( $this->path , 0777 );
            //throw new CHttpException(500, "{$this->path} does not exists.");
        } else if( !is_writable( $this->path ) ) {
            chmod( $this->path, 0777 );
            //throw new CHttpException(500, "{$this->path} is not writable.");
        }

        
 		if (empty($this->_subfolder)){
 			$this->_subfolder = "";
 		}
        	
    }

    /**
     * The main action that handles the file upload request.
     * @since 0.1
     * @author Asgaroth
     */
    public function run( ) {
    	header( 'Vary: Accept' );
        if( isset( $_SERVER['HTTP_ACCEPT'] ) && (strpos( $_SERVER['HTTP_ACCEPT'], 'application/json' ) !== false) ) {
            header( 'Content-type: application/json' );
        } else {
            header( 'Content-type: text/plain' );
        }

        if( isset( $_GET["_method"] ) ) {
            if( $_GET["_method"] == "delete" ) {
                $success = is_file( $_GET["file"] ) && $_GET["file"][0] !== '.' && unlink( $_GET["file"] );
                echo json_encode( $success );
            }
        } else {			        	
        	$this->init( );
            $model = new XUploadForm;
            $model->file = CUploadedFile::getInstance( $model, 'file' );
            if( $model->file !== null ) {
            
            	$arrDimensions = $this->getImageDimensions($_FILES['XUploadForm']['tmp_name']['file']);            	
            	
            	if ($arrDimensions["width"] > Yii::app()->params["grandesAncho"] || $arrDimensions["height"] > Yii::app()->params["grandesAlto"]){
            		$this->resize = true;
            	}
            	
            	
            	
                $model->mime_type = $model->file->getType( );
                
                //Si por alguna razon llega a pasar un archivo que no sea de extension permitida corto el upload
                if (!$this->validateMimeType($model->mime_type)){
                	Yii::log( "XUploadAction: ".CVarDumper::dumpAsString( $model->getErrors( ) ), CLogger::LEVEL_ERROR, "xupload.actions.XUploadAction" );                	
                	$jsonErr = $this->returnJSONError("acceptFileTypes");
                	throw new CHttpException(500, $jsonErr);
                }
                
                $model->size = $model->file->getSize( );
                
                //valida peso de la imagen. Para IE
                if ($model->size > (int)Yii::app()->params["pesoMaximoFotos"]){                	                	
                    Yii::log( "XUploadAction: ".CVarDumper::dumpAsString( $model->getErrors( ) ), CLogger::LEVEL_ERROR, "xupload.actions.XUploadAction" );                	
                	$jsonErr = $this->returnJSONError("maxFileSize");
                	throw new CHttpException(500, $jsonErr);
                }                 
                
                $model->name = $this->makeImageNameUnique(  $model->file->getName( ) );
                $this->imageName =  $model->name;
                
                if( $model->validate( ) ) {
                    
                	$path = ($this->_subfolder != "") ? "{$this->path}/{$this->_subfolder}/" : "{$this->path}/";
                    $publicPath = ($this->_subfolder != "") ? "{$this->publicPath}/{$this->_subfolder}/" : "{$this->publicPath}/";
                    if( !is_dir( $path ) ) {
                        mkdir( $path, 0777, true );
                        chmod ( $path , 0777 );
                    }                                        

                    $model->file->saveAs( $path . $this->imageName); //guardo la imagen

                    $this->uploadedImagePath = $path.$this->imageName;
                    
                    chmod( $path.$this->imageName, 0777 );					
                    
                    $this->mimeType = $model->mime_type;
                    $this->size = $model->size;
//                     echo json_encode( array( array(
//                             "name" => $this->imageName,
//                             "type" => $model->mime_type,
//                             "size" => $model->size,
//                             "url" => $publicPath.$this->imageName,
//                             "thumbnail_url" => $publicPath.$this->imageName,                   		
//                             "delete_type" => "POST"
//                         ) ) );
                                        
                } else {                                   	
                	echo json_encode( array( array( "error" => $model->getErrors( 'file' ), ) ) );
                    Yii::log( "XUploadAction: ".CVarDumper::dumpAsString( $model->getErrors( ) ), CLogger::LEVEL_ERROR, "xupload.actions.XUploadAction" );
                }
            } else {
                throw new CHttpException( 500, "Could not upload file" );
            }
        }
    }
    
    
    
    /**
     * devuelve un array con el ancho y alto de la imagen en pixeles
     * @param string $imageTempName es el string que genera el $_FILES['campo']['tmp_name']
     */
    private function getImageDimensions($imageTempName){
    	$arrImageInfo = getimagesize($imageTempName);
    	
    	list($width, $height, $type, $attr) = $arrImageInfo; 
    	return array( 
    			"width" => $width,
    			"height" => $height,
    			);    	
    }
    
    public function needsResize(){
    	return $this->resize;
    }
    
    public function returnJSON($imagen_id){
    	return json_encode( array( array(
    			"name" => $this->imageName,
    			"type" => $this->mimeType,
    			"size" => $this->size,
    			"url" => $this->imageName,
    			"thumbnail_url" => $this->imageName,
    			"delete_type" => "POST",
    			"imagen_id" => $imagen_id,
    	) ) );
    }
    
    /**
     * Los "Error Codes" estan en extensions/xupload/assets/js/locale.js 
     * @param String $errorCode
     */
    public function returnJSONError($errorCode){
    	if ($errorCode == ""){
    		$errorCode = "emptyResult";
    	}
    	return json_encode( array( array(
    			"error" => $errorCode,
    	) ) );
    }
    
    public function setImageId($imagen_id){
    	$this->imagenId = $imagen_id;
    }
        
    
    private function makeImageNameUnique($str){
    	$str = str_replace(" ", "", $str);
    	$str = Util::removeAccents($str);
    	$extension = substr($str, strrpos($str, "."));    	
    	return substr($str, 0, strrpos($str, ".")) ."_". rand(100, 999) . $extension;
    } 
	
    public function getUploadedImagePath(){
    	return $this->uploadedImagePath;
    }
    
    public function setImageName($name){
    	$this->imageName = $name;
    }
    
    public function getImageName(){
    	return $this->imageName;
    }
    
    private function validateMimeType($mimeType) {    
    	if (array_search($mimeType, $this->allowedTypes) === false){
    		return false;
    	}
    	return true;
    }
    
    public function setSubfolder($folderName){
    	$this->_subfolder = $folderName;
    }
}
